<?php
/**
 * Copyright (C), 2021-2021, Shall Buy Life info. Co., Ltd.
 * FileName: ${FILE_NAME}
 * Description: 说明
 *
 * @author lwl
 * @Create Date    2021/12/24 13:57
 * @Update Date    2021/12/24 13:57 By lwl
 * @version v1.0
 */

namespace Example\Services\Processor\Order;

use Carbon\Carbon;
use Example\Models\Order;
use Example\Services\EcService;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;
use \Example\Constants\OrderConstant;


class OrderService implements OrderConstant
{

    private static $instance = null;

    public static function getInstance()
    {
        if (is_null(self::$instance)) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    /**
     * 防止 new 多个实列
     * 必须私有，别问为啥 上面说原因了
     */
    private function __construct()
    {

    }

    /**
     * 防止clone 多个实列
     * 必须私有，别问为啥 上面说原因了
     */
    private function __clone()
    {

    }

    /**
     * 防止反序列化
     * 必须私有，别问为啥 上面说原因了
     */
    private function __wakeup()
    {

    }

    /**
     * FunctionName：try
     * Description：创建中
     * Author：lwl
     */
    public function try(array $params): array
    {
        DB::beginTransaction();
        try {
            $params = [
                'order_sn' => $params['order']['sn_data'][0]['ordersn'],
                'member_id' => $params['order']['member_id'],
                'status' => OrderConstant::STATUS_CREATE_ING,
                'amount' => 0,
            ];
            if (!Order::query()->create($params)) {
                DB::rollBack();
                Log::channel()->debug('订单-创建-失败', ['订单号' => $params['order_sn']]);
                return ['code' => 500, 'data' => [], 'message' => '创建订单失败'];
            }
        } catch (\Exception $exception) {
            DB::rollBack();
            Log::channel()->debug('订单-创建-异常', ['message' => $exception->getMessage()]);
            return ['code' => 501, 'data' => [], 'message' => $exception->getMessage()];
        }
        DB::commit();
        return ['code' => 200, 'data' => [], 'message' => 'successful'];
    }

    /**
     * FunctionName：confirm
     * Description：创建待支付订单
     * Author：lwl
     */
    public function confirm(string $orderSn): array
    {
        // TODO: Implement waitPayStatus() method.
        DB::beginTransaction();
        try {
            $order = Order::query()->where('order_sn', $orderSn)->first();
            if ($order && !$order->update(['status' => OrderConstant::STATUS_WAIT_PAY])) {
                DB::rollBack();
                Log::channel('order')->info('订单-待支付-失败', ['订单号' => $orderSn]);
                return ['code' => 500, 'data' => [], 'message' => '订单-待支付-失败'];
            }

        } catch (\Exception $exception) {
            DB::rollBack();
            Log::channel('order')->info('订单-待支付-异常', ['订单号' => $orderSn, 'message' => $exception->getMessage()]);
            return ['code' => 500, 'data' => [], 'message' => '订单-待支付-异常'];
        }
        DB::commit();
        return ['code' => 200, 'data' => [], 'message' => 'successful'];
    }

    /**
     * FunctionName：callBack
     * Description：支付回调
     * Author：lwl
     * @param array $params
     * @return array
     */
    public function callBack(array $params): array
    {
        // TODO: Implement cllBack() method.
        Log::channel('order')->info('支付回调参数', $params);
        DB::beginTransaction();
        try {
            $data = [
                'payed_at' => $params['pay_time'] ?? Carbon::now(),
                'pay_type' => $params['pay_type'],
                'status' => OrderConstant::STATUS_PAYED
            ];
            $order = Order::query()->where('order_sn', $params['ordersn'])->first();
            if ($order && !$order->update($data)) {
                DB::rollBack();
                Log::channel('order')->info('订单-支付回调-失败', ['订单号' => $params['ordersn']]);
                return ['code' => 501, 'data' => [], 'message' => '订单-支付回调-失败'];
            }

        } catch (\Exception $exception) {
            DB::rollBack();
            Log::channel('order')->info('订单-支付回调-异常', ['订单号' => $params['ordersn'], 'message' => $exception->getMessage()]);
            return ['code' => 500, 'data' => [], 'message' => '订单-支付回调-异常'];
        }
        DB::commit();
        return ['code' => 200, 'data' => [], 'message' => 'successful'];
    }

    /**
     * FunctionName：cancel
     * Description：取消订单
     * Author：lwl
     * @param string $orderSn
     * @return array
     */
    public function cancel(string $orderSn): array
    {
        DB::beginTransaction();
        try {
            $cacheKey = config('common.cache.order_active_close');
            $update = ['status' => OrderConstant::STATUS_MANUAL_CLOSE];
            if (Redis::get($cacheKey . $orderSn)) {
                $update['close_type'] = 2;
            }
            $order = Order::query()->where('order_sn', $orderSn)->first();
            if ($order && !$order->where(['order_sn' => $orderSn])->update($update)) {
                DB::rollBack();
                Log::channel('order')->info('订单-取消-失败', ['订单号' => $orderSn]);
                return ['code' => 501, 'data' => [], 'message' => '订单-取消-失败'];
            }

        } catch (\Exception $exception) {
            DB::rollBack();
            Log::channel('order')->info('订单取消-错误', ['订单号' => $orderSn, 'message' => $exception->getMessage()]);
            return ['code' => 500, 'data' => [], 'message' => $exception->getMessage()];
        }
        DB::commit();
        return ['code' => 200, 'data' => [], 'message' => 'successful'];
    }

    /**
     * FunctionName：settle
     * Description：结算订单
     * Author：lwl
     * @param array $params
     * @return array
     */
    public function settle(array $params): array
    {
        try {
            EcService::settle('example.order.settle', $params['order_sn']);
            if (($params['is_auto_settle'] ?? -1) == -1) {
                $order = Order::query()->where('order_sn', $params['order_sn'])->first();
                if ($order && !$order->update(['status' => OrderConstant::STATUS_SETTLE])) {
                    Log::channel('order')->info('订单-结算-失败', ['订单号' => $params['ordersn'], 'message' => $exception->getMessage()]);
                    return ['code' => 501, 'data' => [], 'message' => '订单-结算-失败'];
                }
            }
        } catch (\Exception $exception) {
            Log::channel('order')->info('订单-结算-异常', ['订单号' => $params['ordersn'], 'message' => $exception->getMessage()]);
            return ['code' => 500, 'data' => [], 'message' => $exception->getMessage()];
        }
        DB::commit();
        return ['code' => 200, 'data' => [], 'message' => 'successful'];
    }

    /**
     * FunctionName：settleCallBack
     * Description：结算回调（主动结算没回调）
     * Author：lwl
     * @param array $params
     * @return array
     */
    public function settleCallBack(array $params): array
    {
        return [];
    }
}
